package cn.thens.kdroid.sample.test

import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import cn.thens.kdroid.sample.R
import cn.thens.kdroid.sample.common.view.color
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_chart_main.*


class BirdMainActivity : AppCompatActivity() {
    private var showsAll = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chart_main)
    }

    override fun onResume() {
        super.onResume()

        vBird.post {
            refreshChart()
        }

        vToggle.setOnClickListener {
            showsAll = showsAll.not()
            vToggle.text = if (showsAll) "RGB" else "ALL"
            refreshChart()
        }

        vUp.setOnClickListener {
            vBird.moveLineHeight(-7)
            refreshChart()
        }
        vDown.setOnClickListener {
            vBird.moveLineHeight(8)
            refreshChart()
        }
    }

    private fun refreshChart() {
        vBird.pixel()
                .observeOn(Schedulers.io())
                .toList()
                .map {
                    val allEntryList = ArrayList<Entry>()
                    val redEntryList = ArrayList<Entry>()
                    val greenEntryList = ArrayList<Entry>()
                    val blueEntryList = ArrayList<Entry>()
                    it.forEach {
                        val x = it.first.toFloat()
                        val color = it.second
                        val all = (Int.MAX_VALUE.toLong() and color.toLong()).toFloat()
                        val red = Color.red(color).toFloat()
                        val green = Color.green(color).toFloat()
                        val blue = Color.blue(color).toFloat()
                        allEntryList.add(Entry(x, all))
                        redEntryList.add(Entry(x, red))
                        greenEntryList.add(Entry(x, green))
                        blueEntryList.add(Entry(x, blue))
                    }
                    val dataSet = { list: ArrayList<Entry>, label: String, color: Int ->
                        val dataSet = LineDataSet(list, label)
                        dataSet.color = color
                        dataSet.setDrawCircles(false)
                        dataSet
                    }
                    if (showsAll) {
                        listOf(dataSet(allEntryList, "ALL", Color.BLACK))
                    } else {
                        listOf(
//                            dataSet(allEntryList, "ALL", Color.BLACK),
                                dataSet(redEntryList, "RED", Color.RED),
                                dataSet(greenEntryList, "GREEN", Color.GREEN),
                                dataSet(blueEntryList, "BLUE", Color.BLUE)
                        )
                    }
                }
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSuccess {
                    if (it.isNotEmpty()) {
                        vLineChart.data = LineData(it)
                        vLineChart.invalidate()
                    }
                }
                .subscribe()
    }
}

class BirdView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private val paint = Paint()
    private val bitmap: Bitmap by lazy { BitmapFactory.decodeResource(context.resources, R.drawable.ic_bird) }
    private var lineHeight = 0
    private val rect = Rect()


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawBitmap(bitmap, null, rect.reset(0, 0, canvas.width, canvas.height), paint)
        paint.color = color(R.color.colorAccent)
        canvas.drawLine(0F, lineHeight.toFloat(), width.toFloat(), lineHeight.toFloat(), paint)
    }

    private fun Rect.reset(left: Int, top: Int, right: Int, bottom: Int): Rect {
        this.left = left
        this.right = right
        this.top = top
        this.bottom = bottom
        return this
    }

    fun pixel(): Observable<Pair<Int, Int>> {
        return Observable.create {
            val bitmap = getBitmapFromView(this)
            for (i in 0 until width step 5) {
                val pixel = bitmap.getPixel(i, lineHeight - 1)
                it.onNext(i to pixel)
            }
            bitmap.recycle()
            it.onComplete()
        }
    }

    private fun getBitmapFromView(v: View): Bitmap {
        val b = Bitmap.createBitmap(v.width, v.height, Bitmap.Config.RGB_565)
        val c = Canvas(b)
        v.layout(v.left, v.top, v.right, v.bottom)
        // Draw background
        val bgDrawable = v.background
        if (bgDrawable != null)
            bgDrawable.draw(c)
        else
            c.drawColor(Color.WHITE)
        // Draw view to canvas
        v.draw(c)
        return b
    }

    fun moveLineHeight(delta: Int) {
        lineHeight += delta
        invalidate()
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        lineHeight = height / 2
    }
}